#include "router_load.h"

NodeRouterLoad::NodeRouterLoad(Node *parent, NodeRouterLoadParam params) :
    Node(parent)
{
    const_multiplexer = params.multiplexer;
    port_receiver = new ChannelLoadFabricReceiver(this);
    port_receiver_lane = port_receiver->Bus;
    List<int> tmp_893537360;
    for(int temp_884997144=0; temp_884997144<params.routing_map.size(); temp_884997144+=1)
    {
        tmp_893537360.append(0);
    }
    reg_mask_map = tmp_893537360;
    for(int ii=0; ii<params.routing_map.size(); ii+=1)
    {
        reg_mask = 0;
        for(int temp_884997032=0; temp_884997032<params.routing_map[ii].size(); temp_884997032+=1)
        {
            int routing_id = params.routing_map[ii][temp_884997032];
            reg_mask |= (1)<<(routing_id);
        }
        reg_mask_map[ii] = reg_mask;
    }
    List<ChannelLoadFabricSender *> tmp_893518960;
    for(int temp_884996024=0; temp_884996024<params.routing_map.size(); temp_884996024+=1)
    {
        tmp_893518960.append(new ChannelLoadFabricSender(this));
    }
    port_senders = tmp_893518960;
    List<LaneChannelLoadFabricBusSender *> tmp_893518232;
    for(int ii=0; ii<params.routing_map.size(); ii+=1)
    {
        tmp_893518232.append(port_senders[ii]->Bus);
    }
    port_sender_lanes = tmp_893518232;
    reg_is_routing = false;
    List<bool> tmp_893520304;
    for(int temp_885077552=0; temp_885077552<reg_mask_map.size(); temp_885077552+=1)
    {
        tmp_893520304.append(false);
    }
    reg_dispatch = tmp_893520304;
}

NodeTaskList NodeRouterLoad::tasks() const
{
    NodeTaskList list;
    list.append(static_cast<NodeTask>(&NodeRouterLoad::task_routing));
    return list;
}

void NodeRouterLoad::task_routing()
{
    for(int temp_885076544=0; temp_885076544<const_multiplexer; temp_885076544+=1)
    {
        if((!(reg_is_routing))&&(!(port_receiver_lane->is_any_empty())))
        {
            LaneChannelLoadFabricBusPack ret_885063632 = port_receiver->Bus->get();
            reg_in_pid = ret_885063632.pid;
            reg_in_addr = ret_885063632.addr;
            reg_in_data = ret_885063632.data;
            reg_in_sb_addr = ret_885063632.sb_addr;
            reg_in_ain_addr = ret_885063632.ain_addr;
            reg_in_clr = ret_885063632.clr;
            reg_is_routing = true;
            for(int ii=0; ii<reg_mask_map.size(); ii+=1)
            {
                reg_dispatch[ii] = ((reg_in_pid)&(reg_mask_map[ii]))>(0);
            }
        }
        if(!(reg_is_routing))
        {
            continue;
        }
        reg_dispatch_in_progress = false;
        for(int ii=0; ii<reg_dispatch.size(); ii+=1)
        {
            if((reg_dispatch[ii])&&(!(port_sender_lanes[ii]->is_any_full())))
            {
                port_sender_lanes[ii]->put(reg_in_data, reg_in_addr, reg_in_pid, reg_in_sb_addr, reg_in_ain_addr, reg_in_clr);
                reg_dispatch[ii] = false;
                reg_dispatch_in_progress = (reg_dispatch_in_progress)||(reg_dispatch[ii]);
            }
        }
        if(!(reg_dispatch_in_progress))
        {
            reg_is_routing = false;
        }
    }
}